package com.yinhai.httpclient;



import java.security.KeyStore;
import java.security.Security;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

public final class HttpClientManager {

	private static HttpClientManager INSTANCE = null;
	
	private HttpParams httpParams = null;
	private ClientConnectionManager connManager = null;
	private IdleConnEvictorThread concrolThread = null;
	
	private HttpClientManager() {
		
	}
	
	public static HttpClientManager CreateInstance() {
		if(INSTANCE == null){
			INSTANCE = new HttpClientManager();
		}
		return INSTANCE;
	}
	
	public static HttpClientManager GetInstance() {
		return INSTANCE;
	}
	
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}
	/////
	public void initialize() throws Exception {
		if(httpParams != null){
			return;
		}
		httpParams = new BasicHttpParams(); 
		HttpProtocolParams.setContentCharset(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_CONTENTCHARSET);
		HttpProtocolParams.setHttpElementCharset(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_HTTPELEMENTCHARSET);
		HttpProtocolParams.setUseExpectContinue(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_USEEXPECTCONTINUE);
		HttpProtocolParams.setUserAgent(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_USERAGENT);
		HttpProtocolParams.setVersion(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_VERSION);
		HttpConnectionParams.setConnectionTimeout(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_CONNECTIONTIMEOUT);
		HttpConnectionParams.setLinger(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_LINGER);
		HttpConnectionParams.setSocketBufferSize(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_SOCKETBUFFERSIZE);
		HttpConnectionParams.setSoTimeout(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_SOTIMEOUT);
		HttpConnectionParams.setStaleCheckingEnabled(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_STALECHECKINGENABLED);
		HttpConnectionParams.setTcpNoDelay(httpParams, HttpClientContext.HTTPCLIENT_ENGINE_TCPNODELAY);	

		HttpParams params = new BasicHttpParams();
		ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(HttpClientContext.HTTPCLIENT_CONN_MAXPERROUTE));
		ConnManagerParams.setMaxTotalConnections(params, HttpClientContext.HTTPCLIENT_CONN_MAXTOTALCONN);
		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		
		connManager = new ThreadSafeClientConnManager(params, schemeRegistry);
		
		concrolThread = new IdleConnEvictorThread(connManager);
		concrolThread.start();
	}
	
	public void destroy() {
		if(concrolThread != null) {
			concrolThread.shutdown();
			try {
				concrolThread.join();
			} catch(InterruptedException e) {	}
			concrolThread = null;
		}
		if(connManager != null) {
			connManager.shutdown();
			connManager = null;
		}
	}
	
	public synchronized HttpClient createHttpClient() {
		HttpClient httpClient = null;
		if(httpParams != null && connManager != null) {
			httpClient = new DefaultHttpClient(connManager, httpParams.copy());
		}
		notifyAll();
		return httpClient;
	}
}
